home *** CD-ROM | disk | FTP | other *** search
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
-
- * Code to load Mach from AmigaDOS, take over the machine, set up a
- * temporary virtual memory state until Mach's pmap module can get itself
- * together, and run it by way of SIM.
- *
- * Author: Bryan Ford
-
- * Currently this is the one module that requires a commercial program to
- * build. I can't find a free assembler that understands Motorola syntax
- * (gas doesn't) _and_ supports the MMU instructions (A68k doesn't).
- * I've included this module already assembled in 'takeover.bin', but
- * this isn't really a solution.
-
- * Source completely adapted to A68K v2.71 by S. Walter
- * The MMU instructions are still realized as 'DC.W's, later there will
- * hopefully be macros.
-
-
-
- *********************************************************************
-
- *** Library offsets for exec.library
-
- FUNC_CNT SET -30
-
- FUNCDEF MACRO
- _LVO\1 EQU FUNC_CNT
- FUNC_CNT SET FUNC_CNT-6 * Standard offset-6 bytes each
- ENDM
-
- include "ai:exec/exec_lib.i"
-
-
-
- *** Some symbols directly extracted from include/exec/
- *** If neccessary include include files instead
-
- MemList equ 322
-
- LH_HEAD equ 0
- LH_TAIL equ 4
- LH_TAILPRED equ 8
- LH_TYPE equ 12
- LH_pad equ 13
-
- MH_ATTRIBUTES equ 14
- MH_FIRST equ 16
- MH_LOWER equ 20
- MH_UPPER equ 24
- MH_FREE equ 28
- MH_SIZE equ 32
-
- MEMB_PUBLIC equ 0
- MEMF_PUBLIC equ 1
- MEMB_CHIP equ 1
- MEMF_CHIP equ 2
- MEMB_FAST equ 2
- MEMF_FAST equ 4
-
-
-
- *** Bryan's macros
-
- bz macro ; <label> ; Branch if zero
- beq.\0 \1
- endm
-
- bnz macro ; <label> ; Branch if zero
- bne.\0 \1
- endm
-
-
-
- *** Instructions A68k simply does not understand
-
- bhs macro
- bcc.\0 \1
- endm
-
-
-
- *** SIM symbol node
-
- sym_next equ 0 ;+0 Next node in chain
- sym_number equ 4 ;+4 Number of symbols in this node
- sym_length equ 8 ;+8 Length from sym_next to free space
- sym_size equ 12 ;+12 Size of node
- sym_highest equ 16 ;+16 Highest value in node
- sym_lowest equ 20 ;+20 Lowest value in node
- sym_free equ 24 ;+24 Free space in node
- sym_key equ 28 ;+28 Key for node
- sym_first equ 32 ;+32 First symbol
-
- sym_value equ 0 ;+0 Value
- sym_offset equ 4 ;+4 Offset to next value
- sym_namelen equ 6 ;+6 Number of bytes of name
- sym_name equ 7 ;+7 Name
-
-
-
- *** Some nice stuff really needed
-
- MIN_PMEM equ (1*1024*1024) ; Minimum physical memory we can reasonably run in
-
- VM_MIN_KERNEL_ADDRESS equ $40000000 ; Virtual address of kernel (and SIM)
-
- ROMSIZE equ $00ffffec ; Absolute location of ROM size longword
- ROMEND equ $01000000 ; Absolute location of end of ROM
-
-
-
- *********************************************************************
-
- *** entry - Entrypoint from mach.asm
-
- entry
- move.l a0,d6 ; Kernel load image address
-
- lea entry(pc),a4
-
- move.l 4,a6
-
- jsr _LVODisable(a6)
-
- moveq #0,d2 ; Find the largest chunk of fast memory (addr: a2, size: d2)
- moveq #0,d3 ; ...and the size of chip memory (d3)
- move.l MemList+LH_HEAD(a6),a0 ; Assume all memory starts and stops on 64K boundaries
- \findmem
- tst.l (a0)
- bz.b \mem_out
- move.w MH_ATTRIBUTES(a0),d0
-
- btst #MEMB_FAST,d0
- bz.b \notfast
- move.l MH_LOWER(a0),d1
- clr.w d1
- move.l d1,a1
- sub.l MH_UPPER(a0),d1
- clr.w d1
- neg.l d1
- cmp.l d2,d1
- bls.b \notfast
- move.l d1,d2
- move.l a1,a2
- bra.b \notchip
- \notfast
- btst #MEMB_CHIP,d0 ; There may be multiple chip blocks because of programs
- bz.b \notchip ; like ChipMunch. We assume that chip memory is "really"
- move.l MH_UPPER(a0),d1 ; continuous and starts at 0.
- neg.l d1
- clr.w d1
- neg.l d1
- cmp.l d3,d1
- bls.b \notchip
- move.l d1,d3
- \notchip
- move.l (a0),a0
- bra.b \findmem
- \mem_out
- tst.l d3 ; Make sure we found what we were looking for
- bz.b \config_error
- cmp.l #MIN_PMEM,d2
- bhs.b \takeover
- \config_error
- jsr _LVOEnable(a6)
- moveq #20,d0
- rts
-
- \takeover
- jsr _LVOSuperState(a6)
- move.w #$2700,sr
- moveq #0,d0
- dc.w $4e7b,$0002 ;<*** movec d0,cacr
- lea stack_top(pc),sp
-
- move.w #$7fff,$dff096 ; Turn off all DMA
-
- lea ROMEND,a1 ; Sniff out the physical location of the Kickstart ROM
- move.l ROMSIZE,d0
- sub.l d0,a1 ; (assumptions: MMU enabled, short page descriptors,
-
- dc.w $f011,$9f15 ;<*** ptestr #5,(a1),#7,a0
- ; page tables in unmapped memory)
-
- move.l (a0),d1
- clr.b d1
- move.l d1,rom_pstart-entry(a4)
- add.l d0,d1
- move.l d1,rom_pend-entry(a4)
-
- move.l d6,a0 ; Beginning of hunk sizes in hunk_header
- lea 20(a0),a0
-
- move.l #VM_MIN_KERNEL_ADDRESS,d7 ; Kernel VM relocation offset (d7)
- sub.l a2,d7
-
- move.l a2,code_addr-entry(a4) ; Kernel code address
- move.l (a0)+,d0
- lsl.l #2,d0
- move.l a2,a3
- add.l d0,a3
-
- move.l a3,data_addr-entry(a4) ; Kernel data address
- move.l (a0)+,d0
- lsl.l #2,d0
- add.l d0,a3
-
- move.l a3,bss_addr-entry(a4) ; Kernel bss address
- move.l (a0)+,d0 ; Clear it
- \clrbss
- clr.l (a3)+
- subq.l #1,d0
- bhi.b \clrbss
-
- move.l a3,sim_addr-entry(a4) ; SIM program address
- lea sim(pc),a1 ; Copy it
- move.w #(sim_end-sim)/4-1,d0
- \copysim
- move.l (a1)+,(a3)+
- dbra d0,\copysim
-
- move.l a3,sym_addr-entry(a4) ; SIM symbol node address (a3)
- clr.l (a3)+ ; sym_next
- clr.l (a3)+ ; sym_number
- move.l #sym_first,(a3)+ ; sym_length
- clr.l (a3)+ ; sym_size
- move.l kern_end_addr(pc),(a3) ; sym_highest
- add.l d7,(a3)+
- move.l #VM_MIN_KERNEL_ADDRESS,(a3)+ ; sym_lowest
- clr.l (a3)+ ; sym_free
- clr.l (a3)+ ; sym_key
-
- move.l code_addr(pc),a1 ; Code hunk
- bsr copy_hunk
- move.l code_addr(pc),a1
- bsr reloc_hunk
- move.l code_addr(pc),a1
- bsr maybe_symbol_hunk
- addq #4,a0
-
- move.l data_addr(pc),a1 ; Data hunk
- bsr copy_hunk
- move.l data_addr(pc),a1
- bsr reloc_hunk
- move.l data_addr(pc),a1
- bsr maybe_symbol_hunk
- addq #4,a0
-
- addq #8,a0 ; BSS hunk
- move.l bss_addr(pc),a1
- bsr maybe_symbol_hunk
-
- move.l sim_addr(pc),a0 ; Setup the debug server data in SIMbase
- pea 16(a0)
- add.l d7,(sp)
- lea 128(a0),a1
- move.l #112,(a1)+ ; Structure size
- move.l #'MACH',(a1)+
- move.l d2,(a1)+ ; d0 = public memory size
- move.l d3,(a1)+ ; d1 = chip memory size
- clr.l (a1)+ ; d2
- clr.l (a1)+ ; d3
- clr.l (a1)+ ; d4
- clr.l (a1)+ ; d5
- clr.l (a1)+ ; d6
- clr.l (a1)+ ; d7
- move.l a2,(a1)+ ; a0 = public memory (& kernel) physical address
- move.l a3,(a1)+ ; a1 = physical end of kernel, first free address
- move.l rom_pstart(pc),(a1)+ ; a2 = physical start of Kickstart ROM
- move.l rom_pend(pc),(a1)+ ; a3 = physical end of Kickstart ROM
- clr.l (a1)+ ; a4
- clr.l (a1)+ ; a5
- clr.l (a1)+ ; a6
- clr.l (a1)+ ; usp
- move.l sp,(a1)+ ; ssp
- move.l #VM_MIN_KERNEL_ADDRESS,(a1)+ ; pc
- move.w #$2700,(a1)+ ; sr
- move.l sim_addr(pc),(a1) ; reentry routine = reset
- add.l #sim_resethack-sim,(a1)
- add.l d7,(a1)+
- clr.l (a1)+ ; reentry usp
- clr.l (a1)+ ; reentry ssp
- move.w #$2700,(a1)+ ; reentry sr
- clr.l (a1)+ ; textstructure
- clr.l (a1)+ ; task
- clr.l (a1)+ ; segmentlist
- move.l sym_addr(pc),a2
- move.l a2,(a1)+ ; d_symbol
-
- sub.l a2,a3 ; Now that all symbols are processed, finish up the node
- move.l a3,sym_length(a2)
- move.l a3,sym_size(a2)
-
- clr.l -(sp) ; Turn off all translation
- dc.w $f017,$4000 ;<*** pmove.l (sp),tc
- dc.w $f017,$0800 ;<*** pmove.l (sp),tt0
- dc.w $f017,$0c00 ;<*** pmove.l (sp),tt1
-
- moveq #0,d0 ; Make sure the VBR is right for SIM
- dc.w $4e7b,$0801 ;<*** movec d0,vbr
-
- sub.l a0,a0
- move.l #$4E714EF9,(a0)+ ; Help Exec along during a reboot
- lea ROMEND+2,a1
- sub.l ROMSIZE,a1
- move.l a1,(a0)+
- move.l d7,a1 ; Point all the vectors to SIM
- add.l sim_addr(pc),a1
- add.l #sim_traphack-sim,a1
- move.w #$100-2-1,d0
- \simize
- move.l a1,(a0)+
- dbra d0,\simize
-
- move.l #$000f810f,(sp) ; Transparently translate up to $0fffffff
- dc.w $f017,$0800 ;<*** pmove.l (sp),tt0
- neg.l d7 ; Translate the kernel code to its virtual address
- move.l d7,(sp)
- move.l #$80000001,-(sp)
- dc.w $f017,$4800 ;<*** pmove.q (sp),srp
- move.l #$82808880,(sp) ; Doesn't really matter what our geometry is...
- dc.w $f017,$4000 ;<*** pmove.l (sp),tc
- addq #8,sp
-
- rts ; Drop into SIM's debug server (in virtual memory)
-
- *** copy_hunk - Copy code/data hunk to its final resting place
- * a0 = Code/data hunk
- * a1 = Destination memory
- copy_hunk
- addq #4,a0 ; Skip hunk type
- move.l (a0)+,d0
- \copy_hunk
- move.l (a0)+,(a1)+
- subq.l #1,d0
- bhi.b \copy_hunk
- rts
-
- *** reloc_hunk - Process a reloc32 hunk
- * a0 = Reloc32 hunk
- * a1 = Hunk data to relocate
- reloc_hunk
- movem.l d6/a3/a6,-(sp)
- lea hunk_addrs(pc),a6
- addq #4,a0 ; Skip hunk type
- \more
- move.l (a0)+,d0 ; Number of relocs
- bz.b \out
- move.l (a0)+,d1 ; Hunk to relocate to
- lsl.l #2,d1
- move.l a6,a3
- add.l d1,a3
- move.l (a3),d6
- add.l d7,d6 ; Relocate to virtual memory, not physical
- \go
- move.l a1,a3
- add.l (a0)+,a3
- add.l d6,(a3)
- subq.l #1,d0
- bhi.b \go
- bra.b \more
- \out
- movem.l (sp)+,d6/a3/a6
- rts
-
- *** maybe_symbol_hunk - Process a symbol hunk, but only if it exists (do nothing otherwise)
- * a0 = Next hunk, possibly a symbol hunk
- * a1 = Symbol offset for this symbol hunk
- * a3 = Current symbol pointer
- maybe_symbol_hunk
- movem.l d7/a4-a6,-(sp)
- move.l sym_addr(pc),a6
- lea sym_number(a6),a6
- add.l d7,a1 ; Convert physical symbol offset to virtual offset
-
- cmp.l #$3f0,(a0)
- bne.b \out
- addq #4,a0
- \more
- move.l (a0)+,d0
- bz.b \out
- add.l d0,d0
- add.l d0,d0
- move.l a0,a4
- move.l a3,a5
- add.l d0,a0
- move.l (a0)+,d0
- add.l a1,d0
- move.l d0,(a3)+
- addq #3,a3
- moveq #-1,d0
- \name
- addq #1,d0
- move.b (a4)+,(a3)+
- bnz.b \name
- move.b d0,sym_namelen(a5)
- addq #sym_name+1-sym_offset,d0
- move.w d0,sym_offset(a5)
-
- addq.l #1,(a6)
- bra.b \more
- \out
- movem.l (sp)+,d7/a4-a6
- rts
-
-
- *** data
-
- stack ds.b 8192
- stack_top
-
- hunk_addrs
- code_addr ds.l 1
- data_addr ds.l 1
- bss_addr ds.l 1
- kern_end_addr
- sim_addr ds.l 1
- sym_addr ds.l 1
-
- rom_pstart ds.l 1 ; Physical location of Kickstart ROM
- rom_pend ds.l 1
-
-
-
- *** sim - SIM program image
-
- cnop 0,4
- sim incbin "mk:amiga/SIM"
-
- sim_traphack
- move.w 6(sp),-(sp)
- andi.w #$fff,(sp)
- lsr.w (sp)
- lsr.w (sp)
- clr.w -(sp)
- pea sim_sign(pc)
- add.l #sim+12-sim_sign,(sp)
- rts
-
- sim_sign
- dc.l 'OKAY'
- sim_resethack
- lea \ttdata(pc),a0
- dc.w $f010,$0800 ;<*** pmove.l (a0),tt0
- jmp (2)
-
- \ttdata dc.l $000f810f
-
- cnop 0,4
- sim_end
-
- end
-